//
//  This file is part of a five file concatenation of the CwlViews
//  framework with internal interfaces for source inclusion in projects instead
//  of library inclusion.
//  For details, visit: https://github.com/mattgallagher/CwlViews
//
//  Copyright © 2015-2017 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.
//
//  Permission to use, copy, modify, and/or distribute this software for any
//  purpose with or without fee is hereby granted, provided that the above
//  copyright notice and this permission notice appear in all copies.
//
//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
//  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
//  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
//  SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
//  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
//  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
//  IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
//  This file was generated by the CwlUtilsConcat tool on 2018-03-17 06:51:18 +0000 from the following files:
//
//    CwlBackingLayer.swift
//    CwlTableRowMutation.swift
//    CwlGradientLayer.swift
//    CwlWebView.swift
//    CwlStackView.swift
//    CwlLayer.swift
//

#if os(macOS)
import AppKit
#else
import UIKit
#endif

// MARK: ### CwlBackingLayer.swift ###

import QuartzCore

class BackingLayer: DerivedBinder {
	typealias Instance = CALayer
	typealias Inherited = BaseBinder

	var bindings: [Binding]
	
	init(bindings: [Binding]) {
		self.bindings = bindings
	}
	convenience init(_ bindings: Binding...) {
		self.init(bindings: bindings)
	}
	func consumeBindings() -> [Binding] {
		let b = bindings
		bindings = []
		return b
	}
	func applyBindings(to instance: Instance) {
		var preparer = Preparer()
		preparer.prepareBindings(bindings)
		preparer.applyBindings(bindings, instance: instance, storage: Storage(), combine: embedStorageIfInUse)
		bindings = []
	}
	static func bindingToInherited(_ binding: Binding) -> Inherited.Binding? {
		if case .inheritedBinding(let s) = binding { return s } else { return nil }
	}
	
	enum Binding: BackingLayerBinding {
		typealias Binder = BackingLayer
		static func backingLayerBinding(_ binding: BackingLayer.Binding) -> BackingLayer.Binding { return binding }
		
		case inheritedBinding(Inherited.Binding)
		
		//	1. Value bindings may be applied at construction and may subsequently change.
		case affineTransform(DynamicValue<CGAffineTransform>)
		case anchorPoint(DynamicValue<CGPoint>)
		case anchorPointZ(DynamicValue<CGFloat>)
		case actions(DynamicValue<[String: SignalInput<[AnyHashable: Any]?>?]>)
		case backgroundColor(DynamicValue<CGColor?>)
		case borderColor(DynamicValue<CGColor?>)
		case borderWidth(DynamicValue<CGFloat>)
		case bounds(DynamicValue<CGRect>)
		case contents(DynamicValue<Any?>)
		case contentsCenter(DynamicValue<CGRect>)
		case contentsGravity(DynamicValue<String>)
		case contentsRect(DynamicValue<CGRect>)
		case contentsScale(DynamicValue<CGFloat>)
		case cornerRadius(DynamicValue<CGFloat>)
		case isDoubleSided(DynamicValue<Bool>)
		case drawsAsynchronously(DynamicValue<Bool>)
		case edgeAntialiasingMask(DynamicValue<CAEdgeAntialiasingMask>)
		case frame(DynamicValue<CGRect>)
		case isGeometryFlipped(DynamicValue<Bool>)
		case isHidden(DynamicValue<Bool>)
		case magnificationFilter(DynamicValue<String>)
		case masksToBounds(DynamicValue<Bool>)
		case minificationFilter(DynamicValue<String>)
		case minificationFilterBias(DynamicValue<Float>)
		case name(DynamicValue<String>)
		case needsDisplayOnBoundsChange(DynamicValue<Bool>)
		case opacity(DynamicValue<Float>)
		case isOpaque(DynamicValue<Bool>)
		case position(DynamicValue<CGPoint>)
		case rasterizationScale(DynamicValue<CGFloat>)
		case shadowColor(DynamicValue<CGColor?>)
		case shadowOffset(DynamicValue<CGSize>)
		case shadowOpacity(DynamicValue<Float>)
		case shadowPath(DynamicValue<CGPath?>)
		case shadowRadius(DynamicValue<CGFloat>)
		case shouldRasterize(DynamicValue<Bool>)
		case style(DynamicValue<[AnyHashable: Any]>)
		case sublayerTransform(DynamicValue<CATransform3D>)
		case transform(DynamicValue<CATransform3D>)
		case zPosition(DynamicValue<CGFloat>)
		case mask(DynamicValue<LayerInstance?>)
		case sublayers(DynamicValue<[LayerInstance]>)
		
		#if os(macOS)
			case autoresizingMask(DynamicValue<CAAutoresizingMask>)
			case backgroundFilters(DynamicValue<[CIFilter]?>)
			case compositingFilter(DynamicValue<CIFilter?>)
			case filters(DynamicValue<[CIFilter]?>)
		#else
			@available(*, unavailable)
			case autoresizingMask(())
			@available(*, unavailable)
			case backgroundFilters(())
			@available(*, unavailable)
			case compositingFilter(())
			@available(*, unavailable)
			case filters(())
		#endif
		
		//	2. Signal bindings are performed on the object after construction.
		case addAnimation(Signal<AnimationForKey>)
		case needsDisplay(Signal<()>)
		case needsDisplayInRect(Signal<CGRect>)
		case removeAllAnimations(Signal<String>)
		case removeAnimationForKey(Signal<String>)
		case scrollRectToVisible(Signal<CGRect>)
		
		//	3. Action bindings are triggered by the object after construction.
		
		//	4. Delegate bindings require synchronous evaluation within the object's context.
	}
	
	struct Preparer: DerivedPreparer {
		typealias Binder = BackingLayer
		var linkedPreparer = Binder.Inherited.Preparer()
		
		init() {}
		
		func applyBinding(_ binding: Binding, instance: Instance, storage: Storage) -> Cancellable? {
			switch binding {
			case .autoresizingMask(let x):
				#if os(macOS)
					return x.apply(instance, storage) { i, s, v in i.autoresizingMask = v }
				#else
					return nil
				#endif
			case .backgroundFilters(let x):
				#if os(macOS)
					return x.apply(instance, storage) { i, s, v in i.backgroundFilters = v }
				#else
					return nil
				#endif
			case .compositingFilter(let x):
				#if os(macOS)
					return x.apply(instance, storage) { i, s, v in i.compositingFilter = v }
				#else
					return nil
				#endif
			case .filters(let x):
				#if os(macOS)
					return x.apply(instance, storage) { i, s, v in i.filters = v }
				#else
					return nil
				#endif
			case .sublayers(let x):
				return x.apply(instance, storage) { i, s, v in
					i.sublayers = v.map { $0.layerInstance }
				}
			case .affineTransform(let x): return x.apply(instance, storage) { i, s, v in i.setAffineTransform(v) }
			case .anchorPoint(let x): return x.apply(instance, storage) { i, s, v in i.anchorPoint = v }
			case .anchorPointZ(let x): return x.apply(instance, storage) { i, s, v in i.anchorPointZ = v }
			case .backgroundColor(let x): return x.apply(instance, storage) { i, s, v in i.backgroundColor = v }
			case .borderColor(let x): return x.apply(instance, storage) { i, s, v in i.borderColor = v }
			case .borderWidth(let x): return x.apply(instance, storage) { i, s, v in i.borderWidth = v }
			case .bounds(let x): return x.apply(instance, storage) { i, s, v in i.bounds = v }
			case .contents(let x): return x.apply(instance, storage) { i, s, v in i.contents = v }
			case .contentsCenter(let x): return x.apply(instance, storage) { i, s, v in i.contentsCenter = v }
			case .contentsGravity(let x): return x.apply(instance, storage) { i, s, v in i.contentsGravity = v }
			case .contentsRect(let x): return x.apply(instance, storage) { i, s, v in i.contentsRect = v }
			case .contentsScale(let x): return x.apply(instance, storage) { i, s, v in i.contentsScale = v }
			case .cornerRadius(let x): return x.apply(instance, storage) { i, s, v in i.cornerRadius = v }
			case .isDoubleSided(let x): return x.apply(instance, storage) { i, s, v in i.isDoubleSided = v }
			case .drawsAsynchronously(let x): return x.apply(instance, storage) { i, s, v in i.drawsAsynchronously = v }
			case .edgeAntialiasingMask(let x): return x.apply(instance, storage) { i, s, v in i.edgeAntialiasingMask = v }
			case .frame(let x): return x.apply(instance, storage) { i, s, v in i.frame = v }
			case .isGeometryFlipped(let x): return x.apply(instance, storage) { i, s, v in i.isGeometryFlipped = v }
			case .isHidden(let x): return x.apply(instance, storage) { i, s, v in i.isHidden = v }
			case .magnificationFilter(let x): return x.apply(instance, storage) { i, s, v in i.magnificationFilter = v }
			case .masksToBounds(let x): return x.apply(instance, storage) { i, s, v in i.masksToBounds = v }
			case .minificationFilter(let x): return x.apply(instance, storage) { i, s, v in i.minificationFilter = v }
			case .minificationFilterBias(let x): return x.apply(instance, storage) { i, s, v in i.minificationFilterBias = v }
			case .name(let x): return x.apply(instance, storage) { i, s, v in i.name = v }
			case .needsDisplayOnBoundsChange(let x): return x.apply(instance, storage) { i, s, v in i.needsDisplayOnBoundsChange = v }
			case .opacity(let x): return x.apply(instance, storage) { i, s, v in i.opacity = v }
			case .isOpaque(let x): return x.apply(instance, storage) { i, s, v in i.isOpaque = v }
			case .position(let x): return x.apply(instance, storage) { i, s, v in i.position = v }
			case .rasterizationScale(let x): return x.apply(instance, storage) { i, s, v in i.rasterizationScale = v }
			case .shadowColor(let x): return x.apply(instance, storage) { i, s, v in i.shadowColor = v }
			case .shadowOffset(let x): return x.apply(instance, storage) { i, s, v in i.shadowOffset = v }
			case .shadowOpacity(let x): return x.apply(instance, storage) { i, s, v in i.shadowOpacity = v }
			case .shadowPath(let x): return x.apply(instance, storage) { i, s, v in i.shadowPath = v }
			case .shadowRadius(let x): return x.apply(instance, storage) { i, s, v in i.shadowRadius = v }
			case .shouldRasterize(let x): return x.apply(instance, storage) { i, s, v in i.shouldRasterize = v }
			case .style(let x): return x.apply(instance, storage) { i, s, v in i.style = v }
			case .sublayerTransform(let x): return x.apply(instance, storage) { i, s, v in i.sublayerTransform = v }
			case .transform(let x): return x.apply(instance, storage) { i, s, v in i.transform = v }
			case .zPosition(let x): return x.apply(instance, storage) { i, s, v in i.zPosition = v }
			case .addAnimation(let x): return x.apply(instance, storage) { i, s, v in i.add(v.animation, forKey: v.key) }
			case .needsDisplay(let x): return x.apply(instance, storage) { i, s, v in i.setNeedsDisplay() }
			case .needsDisplayInRect(let x): return x.apply(instance, storage) { i, s, v in i.setNeedsDisplay(v) }
			case .removeAllAnimations(let x): return x.apply(instance, storage) { i, s, v in i.removeAllAnimations() }
			case .removeAnimationForKey(let x): return x.apply(instance, storage) { i, s, v in i.removeAnimation(forKey: v) }
			case .scrollRectToVisible(let x): return x.apply(instance, storage) { i, s, v in i.scrollRectToVisible(v) }
			case .actions(let x):
				return x.apply(instance, storage) { i, s, v in
					var actions = i.actions ?? [String: CAAction]()
					for (key, input) in v {
						if let i = input {
							actions[key] = storage
							storage.layerActions[key] = i
						} else {
							actions[key] = NSNull()
							storage.layerActions.removeValue(forKey: key)
						}
					}
					i.actions = actions
				}
			case .mask(let x):
				return x.apply(instance, storage) { i, s, v in
					i.mask = v?.layerInstance
				}
			case .inheritedBinding(let s):
				return linkedPreparer.applyBinding(s, instance: (), storage: ())
			}
		}
	}
	
	class Storage: ObjectBinderStorage, CAAction {
		override var inUse: Bool {
			return super.inUse || !layerActions.isEmpty
		}
		
		// LayerBinderStorage implementation
		var layerActions = [String: SignalInput<[AnyHashable: Any]?>]()
		@objc func run(forKey event: String, object anObject: Any, arguments dict: [AnyHashable: Any]?) {
			_ = layerActions[event]?.send(value: dict)
		}
	}
}

extension BindingName where Binding: BackingLayerBinding {
	// You can easily convert the `Binding` cases to `BindingName` using the following Xcode-style regex:
	// Replace: case ([^\(]+)\((.+)\)$
	// With:    static var $1: BindingName<$2, Binding> { return BindingName<$2, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.$1(v)) }) }
	static var affineTransform: BindingName<DynamicValue<CGAffineTransform>, Binding> { return BindingName<DynamicValue<CGAffineTransform>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.affineTransform(v)) }) }
	static var anchorPoint: BindingName<DynamicValue<CGPoint>, Binding> { return BindingName<DynamicValue<CGPoint>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.anchorPoint(v)) }) }
	static var anchorPointZ: BindingName<DynamicValue<CGFloat>, Binding> { return BindingName<DynamicValue<CGFloat>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.anchorPointZ(v)) }) }
	static var actions: BindingName<DynamicValue<[String: SignalInput<[AnyHashable: Any]?>?]>, Binding> { return BindingName<DynamicValue<[String: SignalInput<[AnyHashable: Any]?>?]>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.actions(v)) }) }
	static var backgroundColor: BindingName<DynamicValue<CGColor?>, Binding> { return BindingName<DynamicValue<CGColor?>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.backgroundColor(v)) }) }
	static var borderColor: BindingName<DynamicValue<CGColor?>, Binding> { return BindingName<DynamicValue<CGColor?>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.borderColor(v)) }) }
	static var borderWidth: BindingName<DynamicValue<CGFloat>, Binding> { return BindingName<DynamicValue<CGFloat>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.borderWidth(v)) }) }
	static var bounds: BindingName<DynamicValue<CGRect>, Binding> { return BindingName<DynamicValue<CGRect>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.bounds(v)) }) }
	static var contents: BindingName<DynamicValue<Any?>, Binding> { return BindingName<DynamicValue<Any?>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.contents(v)) }) }
	static var contentsCenter: BindingName<DynamicValue<CGRect>, Binding> { return BindingName<DynamicValue<CGRect>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.contentsCenter(v)) }) }
	static var contentsGravity: BindingName<DynamicValue<String>, Binding> { return BindingName<DynamicValue<String>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.contentsGravity(v)) }) }
	static var contentsRect: BindingName<DynamicValue<CGRect>, Binding> { return BindingName<DynamicValue<CGRect>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.contentsRect(v)) }) }
	static var contentsScale: BindingName<DynamicValue<CGFloat>, Binding> { return BindingName<DynamicValue<CGFloat>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.contentsScale(v)) }) }
	static var cornerRadius: BindingName<DynamicValue<CGFloat>, Binding> { return BindingName<DynamicValue<CGFloat>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.cornerRadius(v)) }) }
	static var isDoubleSided: BindingName<DynamicValue<Bool>, Binding> { return BindingName<DynamicValue<Bool>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.isDoubleSided(v)) }) }
	static var drawsAsynchronously: BindingName<DynamicValue<Bool>, Binding> { return BindingName<DynamicValue<Bool>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.drawsAsynchronously(v)) }) }
	static var edgeAntialiasingMask: BindingName<DynamicValue<CAEdgeAntialiasingMask>, Binding> { return BindingName<DynamicValue<CAEdgeAntialiasingMask>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.edgeAntialiasingMask(v)) }) }
	static var frame: BindingName<DynamicValue<CGRect>, Binding> { return BindingName<DynamicValue<CGRect>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.frame(v)) }) }
	static var isGeometryFlipped: BindingName<DynamicValue<Bool>, Binding> { return BindingName<DynamicValue<Bool>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.isGeometryFlipped(v)) }) }
	static var isHidden: BindingName<DynamicValue<Bool>, Binding> { return BindingName<DynamicValue<Bool>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.isHidden(v)) }) }
	static var magnificationFilter: BindingName<DynamicValue<String>, Binding> { return BindingName<DynamicValue<String>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.magnificationFilter(v)) }) }
	static var masksToBounds: BindingName<DynamicValue<Bool>, Binding> { return BindingName<DynamicValue<Bool>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.masksToBounds(v)) }) }
	static var minificationFilter: BindingName<DynamicValue<String>, Binding> { return BindingName<DynamicValue<String>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.minificationFilter(v)) }) }
	static var minificationFilterBias: BindingName<DynamicValue<Float>, Binding> { return BindingName<DynamicValue<Float>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.minificationFilterBias(v)) }) }
	static var name: BindingName<DynamicValue<String>, Binding> { return BindingName<DynamicValue<String>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.name(v)) }) }
	static var needsDisplayOnBoundsChange: BindingName<DynamicValue<Bool>, Binding> { return BindingName<DynamicValue<Bool>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.needsDisplayOnBoundsChange(v)) }) }
	static var opacity: BindingName<DynamicValue<Float>, Binding> { return BindingName<DynamicValue<Float>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.opacity(v)) }) }
	static var isOpaque: BindingName<DynamicValue<Bool>, Binding> { return BindingName<DynamicValue<Bool>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.isOpaque(v)) }) }
	static var position: BindingName<DynamicValue<CGPoint>, Binding> { return BindingName<DynamicValue<CGPoint>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.position(v)) }) }
	static var rasterizationScale: BindingName<DynamicValue<CGFloat>, Binding> { return BindingName<DynamicValue<CGFloat>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.rasterizationScale(v)) }) }
	static var shadowColor: BindingName<DynamicValue<CGColor?>, Binding> { return BindingName<DynamicValue<CGColor?>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.shadowColor(v)) }) }
	static var shadowOffset: BindingName<DynamicValue<CGSize>, Binding> { return BindingName<DynamicValue<CGSize>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.shadowOffset(v)) }) }
	static var shadowOpacity: BindingName<DynamicValue<Float>, Binding> { return BindingName<DynamicValue<Float>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.shadowOpacity(v)) }) }
	static var shadowPath: BindingName<DynamicValue<CGPath?>, Binding> { return BindingName<DynamicValue<CGPath?>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.shadowPath(v)) }) }
	static var shadowRadius: BindingName<DynamicValue<CGFloat>, Binding> { return BindingName<DynamicValue<CGFloat>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.shadowRadius(v)) }) }
	static var shouldRasterize: BindingName<DynamicValue<Bool>, Binding> { return BindingName<DynamicValue<Bool>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.shouldRasterize(v)) }) }
	static var style: BindingName<DynamicValue<[AnyHashable: Any]>, Binding> { return BindingName<DynamicValue<[AnyHashable: Any]>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.style(v)) }) }
	static var sublayerTransform: BindingName<DynamicValue<CATransform3D>, Binding> { return BindingName<DynamicValue<CATransform3D>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.sublayerTransform(v)) }) }
	static var transform: BindingName<DynamicValue<CATransform3D>, Binding> { return BindingName<DynamicValue<CATransform3D>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.transform(v)) }) }
	static var zPosition: BindingName<DynamicValue<CGFloat>, Binding> { return BindingName<DynamicValue<CGFloat>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.zPosition(v)) }) }
	static var mask: BindingName<DynamicValue<LayerInstance?>, Binding> { return BindingName<DynamicValue<LayerInstance?>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.mask(v)) }) }
	static var sublayers: BindingName<DynamicValue<[LayerInstance]>, Binding> { return BindingName<DynamicValue<[LayerInstance]>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.sublayers(v)) }) }
	#if os(macOS)
		static var autoresizingMask: BindingName<DynamicValue<CAAutoresizingMask>, Binding> { return BindingName<DynamicValue<CAAutoresizingMask>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.autoresizingMask(v)) }) }
		static var backgroundFilters: BindingName<DynamicValue<[CIFilter]?>, Binding> { return BindingName<DynamicValue<[CIFilter]?>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.backgroundFilters(v)) }) }
		static var compositingFilter: BindingName<DynamicValue<CIFilter?>, Binding> { return BindingName<DynamicValue<CIFilter?>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.compositingFilter(v)) }) }
		static var filters: BindingName<DynamicValue<[CIFilter]?>, Binding> { return BindingName<DynamicValue<[CIFilter]?>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.filters(v)) }) }
	#endif
	static var addAnimation: BindingName<Signal<AnimationForKey>, Binding> { return BindingName<Signal<AnimationForKey>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.addAnimation(v)) }) }
	static var needsDisplay: BindingName<Signal<()>, Binding> { return BindingName<Signal<()>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.needsDisplay(v)) }) }
	static var needsDisplayInRect: BindingName<Signal<CGRect>, Binding> { return BindingName<Signal<CGRect>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.needsDisplayInRect(v)) }) }
	static var removeAllAnimations: BindingName<Signal<String>, Binding> { return BindingName<Signal<String>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.removeAllAnimations(v)) }) }
	static var removeAnimationForKey: BindingName<Signal<String>, Binding> { return BindingName<Signal<String>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.removeAnimationForKey(v)) }) }
	static var scrollRectToVisible: BindingName<Signal<CGRect>, Binding> { return BindingName<Signal<CGRect>, Binding>({ v in .backingLayerBinding(BackingLayer.Binding.scrollRectToVisible(v)) }) }
}

protocol BackingLayerBinding: BaseBinding {
	static func backingLayerBinding(_ binding: BackingLayer.Binding) -> Self
}

extension BackingLayerBinding {
	static func baseBinderBinding(_ binding: BaseBinder.Binding) -> Self {
		return Self.backingLayerBinding(.inheritedBinding(binding))
	}
}

struct AnimationForKey {
	let animation: CAAnimation
	let key: String?
	
	init(animation: CAAnimation, forKey: String? = nil) {
		self.animation = animation
		self.key = forKey
	}
	
	static var fade: AnimationForKey {
		let t = CATransition()
		t.type = kCATransitionFade
		return AnimationForKey(animation: t)
	}
	
	enum Direction {
		case left
		case right
		case top
		case bottom
		
		func transition(ofType: String) -> AnimationForKey {
			let t = CATransition()
			t.type = ofType
			switch self {
			case .left: t.subtype = kCATransitionFromLeft
			case .right: t.subtype = kCATransitionFromRight
			case .top: t.subtype = kCATransitionFromTop
			case .bottom: t.subtype = kCATransitionFromBottom
			}
			return AnimationForKey(animation: t)
		}
	}
	
	static func moveIn(from: Direction) -> AnimationForKey {
		return from.transition(ofType: kCATransitionMoveIn)
	}
	
	static func push(from: Direction) -> AnimationForKey {
		return from.transition(ofType: kCATransitionPush)
	}
	
	static func reveal(from: Direction) -> AnimationForKey {
		return from.transition(ofType: kCATransitionReveal)
	}
}

// MARK: ### CwlTableRowMutation.swift ###

/// This data type models updates to the visible rows of a single-dimensional array in a scrolling view.
/// A combination of a `ArrayMutation` and an `AnimationType` which specifies how that mutation should be displayed, along with a local offset and global count which track a global array of which the `ArrayMutation` might merely be a subrange.
/// This type can communicate changes to rows in an `NSTableView` or sections in a `UITableView`. When `Value` is a `TableSectionMutation`, this type can model a two-tiered `UITableView` with multiple sections.
struct TableRowMutation<Value>: ExpressibleByArrayLiteral {
	#if os(macOS)
		typealias AnimationType = NSTableView.AnimationOptions
	#elseif os(iOS)
		typealias AnimationType = UITableViewRowAnimation
	#else
		typealias AnimationType = Int
	#endif
	
	/// A `TableRowMutation` is primarily an `ArrayMutation` with some additional features suitable for animating an 
	let arrayMutation: ArrayMutation<Value>
	
	/// This is offset for the `arrayMutation` in greater array *after* the mutation is applied.
	let localOffset: Int
	
	/// This is the length of the greater array *after* the mutation is applied.
	let globalCount: Int
	
	/// This is the animation to use for the mutation
	let animation: AnimationType
	
	init(arrayMutation: ArrayMutation<Value>, localOffset: Int = 0, globalCount: Int? = nil, animation: AnimationType = defaultTableViewAnimation) {
		self.arrayMutation = arrayMutation
		self.localOffset = localOffset
		self.globalCount = globalCount ?? arrayMutation.values.count
		self.animation = animation
	}
	
	init(arrayLiteral elements: Value...) {
		self.init(arrayMutation: ArrayMutation(reload: elements), localOffset: 0, globalCount: elements.count, animation: noTableViewAnimation)
	}
	
	init(array elements: [Value]) {
		self.init(arrayMutation: ArrayMutation(reload: elements), localOffset: 0, globalCount: elements.count, animation: noTableViewAnimation)
	}
	
	func apply(to rowState: inout TableRowState<Value>) {
		arrayMutation.apply(to: &rowState.rows)
		rowState.localOffset = localOffset
		rowState.globalCount = globalCount
	}
	
	static func defaultAnimation(_ kind: ArrayMutationKind) -> AnimationType {
		switch kind {
		case .update: fallthrough
		case .reload: fallthrough
		case .scroll: return noTableViewAnimation
		default: return defaultTableViewAnimation
		}
	}
}

extension IndexSet {
	/// Maintaining an `ArrayMutation` with a local offset may require offsetting an `IndexSet`
	func offset(by: Int) -> IndexSet {
		if by == 0 {
			return self
		}
		var result = IndexSet()
		for range in self.rangeView {
			result.insert(integersIn: (range.startIndex + by)..<(range.endIndex + by))
		}
		return result
	}
}

#if os(macOS)
	let defaultTableViewAnimation = NSTableView.AnimationOptions.effectFade
#elseif os(iOS)
	let defaultTableViewAnimation = UITableViewRowAnimation.automatic
#else
	let defaultTableViewAnimation = 0
#endif

#if os(macOS)
	let noTableViewAnimation = NSTableView.AnimationOptions()
#elseif os(iOS)
	let noTableViewAnimation = UITableViewRowAnimation.none
#else
	let noTableViewAnimation = 0
#endif

/// A data type that can be used to cache the destination end of a `TableRowMutation<Value>` change stream.
struct TableRowState<Value> {
	var rows: Deque<Value> = []
	var localOffset: Int = 0
	var globalCount: Int = 0
	init() {}
}

private var associatedInputKey = NSObject()
func getSignalInput<B>(for object: NSObject, valueType: B.Type) -> 
SignalInput<B>? {
	return objc_getAssociatedObject(object, &associatedInputKey) as? SignalInput<B>
}

func setSignalInput<B>(for object: NSObject, to input: SignalInput<B>) {
	objc_setAssociatedObject(object, &associatedInputKey, input, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}

// MARK: ### CwlGradientLayer.swift ###

class GradientLayer: ConstructingBinder, GradientLayerInstance {
	typealias Instance = CAGradientLayer
	typealias Inherited = Layer
	
	var state: BinderState<Instance, BinderParameters<Instance, Binding>>
	required init(subclass: Instance.Type = Instance.self, bindings: [Binding]) {
		state = .pending(BinderParameters(subclass: subclass, bindings: bindings))
	}
	static func bindingToInherited(_ binding: Binding) -> Inherited.Binding? {
		if case .inheritedBinding(let s) = binding { return s } else { return nil }
	}
	var gradientLayerInstance: Instance { return instance() }

	enum Binding: GradientLayerBinding {
		typealias Binder = GradientLayer
		static func gradientLayerBinding(_ binding: Binding) -> Binding { return binding }
		case inheritedBinding(Inherited.Binding)
		
		//	1. Value bindings may be applied at construction and may subsequently change.
		case colors(DynamicValue<[CGColor]>)
		case locations(DynamicValue<[CGFloat]>)
		case endPoint(DynamicValue<CGPoint>)
		case startPoint(DynamicValue<CGPoint>)

		// 2. Signal bindings are performed on the object after construction.

		// 3. Action bindings are triggered by the object after construction.

	  // 4. Delegate bindings require synchronous evaluation within the object's context.
	}

	struct Preparer: ConstructingPreparer {
		typealias Binder = GradientLayer
		var linkedPreparer = Inherited.Preparer()
		
		func constructStorage() -> Binder.Storage { return Storage() }
		func constructInstance(subclass: Binder.Instance.Type) -> Binder.Instance { return subclass.init() }
		
		init() {}
		
		func applyBinding(_ binding: Binding, instance: Instance, storage: Storage) -> Cancellable? {
			switch binding {
			case .colors(let x): return x.apply(instance, storage) { i, s, v in i.colors = v }
			case .locations(let x): return x.apply(instance, storage) { i, s, v in i.locations = v.map { NSNumber(value: Double($0)) } }
			case .endPoint(let x): return x.apply(instance, storage) { i, s, v in i.endPoint = v }
			case .startPoint(let x): return x.apply(instance, storage) { i, s, v in i.startPoint = v }
			case .inheritedBinding(let s): return linkedPreparer.applyBinding(s, instance: instance, storage: storage)
			}
		}
	}

	typealias Storage = Layer.Storage
}

extension BindingName where Binding: GradientLayerBinding {
	// You can easily convert the `Binding` cases to `BindingName` using the following Xcode-style regex:
	// Replace: case ([^\(]+)\((.+)\)$
	// With:    static var $1: BindingName<$2, Binding> { return BindingName<$2, Binding>({ v in .gradientLayerBinding(GradientLayer.Binding.$1(v)) }) }
	static var colors: BindingName<DynamicValue<[CGColor]>, Binding> { return BindingName<DynamicValue<[CGColor]>, Binding>({ v in .gradientLayerBinding(GradientLayer.Binding.colors(v)) }) }
	static var locations: BindingName<DynamicValue<[CGFloat]>, Binding> { return BindingName<DynamicValue<[CGFloat]>, Binding>({ v in .gradientLayerBinding(GradientLayer.Binding.locations(v)) }) }
	static var endPoint: BindingName<DynamicValue<CGPoint>, Binding> { return BindingName<DynamicValue<CGPoint>, Binding>({ v in .gradientLayerBinding(GradientLayer.Binding.endPoint(v)) }) }
	static var startPoint: BindingName<DynamicValue<CGPoint>, Binding> { return BindingName<DynamicValue<CGPoint>, Binding>({ v in .gradientLayerBinding(GradientLayer.Binding.startPoint(v)) }) }
}

protocol GradientLayerInstance: LayerInstance {
	var gradientLayerInstance: GradientLayer.Instance { get }
}
extension GradientLayerInstance {
	var layerInstance: Layer.Instance { return gradientLayerInstance }
}
extension GradientLayer.Instance: GradientLayerInstance {
	var gradientLayerInstance: GradientLayer.Instance { return self }
}

protocol GradientLayerBinding: LayerBinding {
	static func gradientLayerBinding(_ binding: GradientLayer.Binding) -> Self
}

extension GradientLayerBinding {
	static func layerBinding(_ binding: Layer.Binding) -> Self {
		return Self.gradientLayerBinding(.inheritedBinding(binding))
	}
}

// MARK: ### CwlWebView.swift ###

import WebKit

class WebView: ConstructingBinder, WebViewInstance {
	typealias Instance = WKWebView
	typealias Inherited = View
	
	var state: BinderConstructionState<Instance, Binding>
	required init(subclass: Instance.Type = Instance.self, bindings: [Binding]) {
		state = .pending(BinderParameters(subclass: subclass, bindings: bindings))
	}
	static func bindingToInherited(_ binding: Binding) -> Inherited.Binding? {
		if case .inheritedBinding(let s) = binding { return s } else { return nil }
	}
	var webViewInstance: Instance { return instance() }
	
	enum Binding: WebViewBinding {
		typealias Binder = WebView
		static func webViewBinding(_ binding: Binding) -> Binding { return binding }
		case inheritedBinding(Inherited.Binding)
		
		//	0. Static bindings are applied at construction and are subsequently immutable.
		case configuration(StaticValue<WKWebViewConfiguration>)
		#if os(iOS)
		case scrollView(StaticValue<ScrollView>)
		#else
		@available(*, unavailable)
		case scrollViewBindings(())
		#endif
		
		//	1. Value bindings may be applied at construction and may subsequently change.
		@available(macOS 10.11, *)
		case customUserAgent(DynamicValue<String?>)
		#if os(macOS)
			case allowsMagnification(DynamicValue<Bool>)
			case magnification(DynamicValue<(factor: CGFloat, centeredAt: CGPoint)>)
		#else
			@available(*, unavailable)
			case allowsMagnification(())
			@available(*, unavailable)
			case magnification(())
		#endif
		case allowsBackForwardNavigationGestures(DynamicValue<Bool>)
		@available(macOS 10.11, *)
		case allowsLinkPreview(DynamicValue<Bool>)
		
		//	2. Signal bindings are performed on the object after construction.
		case load(Signal<(request: URLRequest, SignalInput<WKNavigation?>?)>)
		@available(macOS 10.11, *)
		case loadFile(Signal<(url: URL, allowingReadAccessTo: URL, SignalInput<WKNavigation?>?)>)
		case loadHTMLString(Signal<(string: String, baseURL: URL?, SignalInput<WKNavigation?>?)>)
		@available(macOS 10.11, *)
		case loadData(Signal<(data: Data, mimeType: String, baseURL: URL, characterEncodingName: String, SignalInput<WKNavigation?>?)>)
		case reload(Signal<SignalInput<WKNavigation?>?>)
		case reloadFromOrigin(Signal<SignalInput<WKNavigation?>?>)
		case goBack(Signal<SignalInput<WKNavigation?>?>)
		case goForward(Signal<SignalInput<WKNavigation?>?>)
		case goTo(Signal<(WKBackForwardListItem, SignalInput<WKNavigation?>?)>)
		case stopLoading(Signal<()>)
		case evaluateJavaScript(Signal<(javaScriptString: String, SignalInput<(Any?, Error?)>?)>)
		
		//	3. Action bindings are triggered by the object after construction.
		case didCommit(SignalInput<WKNavigation>)
		case didStartProvisionalNavigation(SignalInput<WKNavigation>)
		case didReceiveServerRedirectForProvisionalNavigation(SignalInput<WKNavigation>)
		case didFail(SignalInput<(WKNavigation, Error)>)
		case didFailProvisionalNavigation(SignalInput<(WKNavigation, Error)>)
		case didFinish(SignalInput<WKNavigation>)
		case contentProcessDidTerminate(SignalInput<()>)
		case decideActionPolicy(SignalInput<(WKNavigationAction, SignalInput<WKNavigationActionPolicy>)>)
		case decideResponsePolicy(SignalInput<(WKNavigationResponse, SignalInput<WKNavigationResponsePolicy>)>)
		case didReceiveAuthenticationChallenge(SignalInput<(URLAuthenticationChallenge, SignalInput<(URLSession.AuthChallengeDisposition, URLCredential?)>)>)
		case runJavaScriptAlertPanel(SignalInput<(message: String, frame: WKFrameInfo, SignalInput<()>)>)
		case runJavaScriptConfirmPanel(SignalInput<(message: String, frame: WKFrameInfo, SignalInput<Bool>)>)
		case runJavaScriptTextInputPanel(SignalInput<(prompt: String, defaultText: String?, frame: WKFrameInfo, SignalInput<String?>)>)
		@available(OSX 10.11, iOS 9.0, *)
		case didClose(SignalInput<()>)
		#if os(macOS)
			@available(OSX 10.12, *)
			case runOpenPanel(SignalInput<(parameters: WKOpenPanelParameters, frame: WKFrameInfo, completion: SignalInput<[URL]?>)>)
		#else
			@available(*, unavailable)
			case runOpenPanel(())
		#endif
		
		//	4. Delegate bindings require synchronous evaluation within the object's context.
		case createWebView((_ webView: WKWebView, _ with: WKWebViewConfiguration, _ for: WKNavigationAction, _ windowFeatures: WKWindowFeatures) -> WKWebView?)
		#if os(iOS)
			@available(iOS 10.0, *)
			case shouldPreviewElement((_ webView: WKWebView, _ elementInfo: WKPreviewElementInfo) -> Bool)
			@available(iOS 10.0, *)
			case previewingViewController((_ webView: WKWebView, _ elementInfo: WKPreviewElementInfo, _ previewActions: [WKPreviewActionItem]) -> UIViewController?)
			@available(iOS 10.0, *)
			case commitPreviewingViewController((_ webView: WKWebView, _ previewingViewController: UIViewController) -> Void)
		#else
			@available(*, unavailable)
			case shouldPreviewElement(())
			@available(*, unavailable)
			case previewingViewController(())
			@available(*, unavailable)
			case commitPreviewingViewController(())
		#endif
	}

	struct Preparer: ConstructingPreparer {
		typealias Binder = WebView
		var linkedPreparer = Inherited.Preparer()
		
		func constructStorage() -> Binder.Storage { return Storage() }
		func constructInstance(subclass: Binder.Instance.Type) -> Binder.Instance { return subclass.init(frame: .zero, configuration: configuration ?? WKWebViewConfiguration()) }
		
		init() {
			self.init(delegateClass: Delegate.self)
		}
		init<Value>(delegateClass: Value.Type) where Value: Delegate {
			self.delegateClass = delegateClass
		}
		let delegateClass: Delegate.Type
		var possibleDelegate: Delegate? = nil
		mutating func delegate() -> Delegate {
			if let d = possibleDelegate {
				return d
			} else {
				let d = delegateClass.init()
				possibleDelegate = d
				return d
			}
		}
		
		var configuration: WKWebViewConfiguration?
		
		mutating func prepareBinding(_ binding: Binding) {
			switch binding {
			case .configuration(let x): configuration = x.value
			case .didCommit(let x):
				let s = #selector(WKNavigationDelegate.webView(_:didCommit:))
				delegate().addSelector(s).didCommit = x
			case .didStartProvisionalNavigation(let x):
				let s = #selector(WKNavigationDelegate.webView(_:didStartProvisionalNavigation:))
				delegate().addSelector(s).didStartProvisionalNavigation = x
			case .didReceiveServerRedirectForProvisionalNavigation(let x):
				let s = #selector(WKNavigationDelegate.webView(_:didReceiveServerRedirectForProvisionalNavigation:))
				delegate().addSelector(s).didReceiveServerRedirectForProvisionalNavigation = x
			case .didFail(let x):
				let s = #selector(WKNavigationDelegate.webView(_:didFail:withError:))
				delegate().addSelector(s).didFail = x
			case .didFailProvisionalNavigation(let x):
				let s = #selector(WKNavigationDelegate.webView(_:didFailProvisionalNavigation:withError:))
				delegate().addSelector(s).didFailProvisionalNavigation = x
			case .didFinish(let x):
				let s = #selector(WKNavigationDelegate.webView(_:didFinish:))
				delegate().addSelector(s).didFinish = x
			case .contentProcessDidTerminate(let x):
				if #available(OSX 10.11, *) {
					let s = #selector(WKNavigationDelegate.webViewWebContentProcessDidTerminate(_:))
					delegate().addSelector(s).contentProcessDidTerminate = x
				}
			case .decideActionPolicy(let x):
				let s = #selector(WKNavigationDelegate.webView(_:decidePolicyFor:decisionHandler:) as ((WKNavigationDelegate) -> (WKWebView,WKNavigationAction, @escaping (WKNavigationActionPolicy) -> Void) -> Void)?)
				delegate().addSelector(s).decideActionPolicy = x
			case .decideResponsePolicy(let x):
				let s = #selector(WKNavigationDelegate.webView(_:decidePolicyFor:decisionHandler:) as ((WKNavigationDelegate) -> (WKWebView, WKNavigationResponse, @escaping (WKNavigationResponsePolicy) -> Void) -> Void)?)
				delegate().addSelector(s).decideResponsePolicy = x
			case .didReceiveAuthenticationChallenge(let x):
				let s = #selector(WKNavigationDelegate.webView(_:didReceive:completionHandler:))
				delegate().addSelector(s).didReceiveAuthenticationChallenge = x
			case .runJavaScriptAlertPanel(let x):
				let s = #selector(WKUIDelegate.webView(_:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:))
				delegate().addSelector(s).runJavaScriptAlertPanel = x
			case .runJavaScriptConfirmPanel(let x):
				let s = #selector(WKUIDelegate.webView(_:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:))
				delegate().addSelector(s).runJavaScriptConfirmPanel = x
			case .runJavaScriptTextInputPanel(let x):
				let s = #selector(WKUIDelegate.webView(_:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:))
				delegate().addSelector(s).runJavaScriptTextInputPanel = x
			case .createWebView(let x):
				let s = #selector(WKUIDelegate.webView(_:createWebViewWith:for:windowFeatures:))
				delegate().addSelector(s).createWebView = x
			case .didClose(let x):
				if #available(OSX 10.11, iOS 9.0, *) {
					let s = #selector(WKUIDelegate.webViewDidClose(_:))
					delegate().addSelector(s).didClose = x
				}
			case .runOpenPanel(let x):
				#if os(macOS)
					if #available(OSX 10.12, *) {
						let s = #selector(WKUIDelegate.webView(_:runOpenPanelWith:initiatedByFrame:completionHandler:))
						delegate().addSelector(s).runOpenPanel = x
					}
				#endif
			case .shouldPreviewElement(let x):
				#if os(iOS)
					if #available(iOS 10.0, *) {
						let s = #selector(WKUIDelegate.webView(_:shouldPreviewElement:))
						delegate().addSelector(s).shouldPreviewElement = x
					}
				#endif
			case .previewingViewController(let x):
				#if os(iOS)
					if #available(iOS 10.0, *) {
						let s = #selector(WKUIDelegate.webView(_:previewingViewControllerForElement:defaultActions:))
						delegate().addSelector(s).previewingViewController = x
					}
				#endif
			case .commitPreviewingViewController(let x):
				#if os(iOS)
					if #available(iOS 10.0, *) {
						let s = #selector(WKUIDelegate.webView(_:commitPreviewingViewController:))
						delegate().addSelector(s).commitPreviewingViewController = x
					}
				#endif
			case .inheritedBinding(let x): linkedPreparer.prepareBinding(x)
			default: break
			}
		}
		
		mutating func prepareInstance(_ instance: Instance, storage: Storage) {
			if possibleDelegate != nil {
				precondition(instance.navigationDelegate == nil && instance.uiDelegate == nil, "Conflicting delegate applied to instance")
				storage.dynamicDelegate = possibleDelegate
				instance.navigationDelegate = storage
				instance.uiDelegate = storage
			}
			
			linkedPreparer.prepareInstance(instance, storage: storage)
		}

		func applyBinding(_ binding: Binding, instance: Instance, storage: Storage) -> Cancellable? {
			switch binding {
			case .configuration: return nil
			case .scrollView(let x):
				#if os(macOS)
					return nil
				#else
					x.value.applyBindings(to: instance.scrollView)
					return nil
				#endif
			case .customUserAgent(let x):
				return x.apply(instance, storage) { i, s, v in
					if #available(OSX 10.11, *) {
						i.customUserAgent = v
					}
				}
			case .allowsMagnification(let x):
				#if os(macOS)
					return x.apply(instance, storage) { i, s, v in i.allowsMagnification = v }
				#else
					return nil
				#endif
			case .magnification(let x):
				#if os(macOS)
					return x.apply(instance, storage) { i, s, v in i.setMagnification(v.factor, centeredAt: v.centeredAt) }
				#else
					return nil
				#endif
			case .allowsBackForwardNavigationGestures(let x): return x.apply(instance, storage) { i, s, v in i.allowsBackForwardNavigationGestures = v }
			case .allowsLinkPreview(let x):
				return x.apply(instance, storage) { i, s, v in
					if #available(OSX 10.11, *) {
						i.allowsLinkPreview = v
					}
				}
			case .load(let x):
				return x.apply(instance, storage) { i, s, v in
					let n = i.load(v.request)
					v.1?.send(value: n)
				}
			case .loadFile(let x):
				return x.apply(instance, storage) { i, s, v in
					if #available(OSX 10.11, *) {
						let n = i.loadFileURL(v.url, allowingReadAccessTo: v.allowingReadAccessTo)
						v.2?.send(value: n)
					}
				}
			case .loadHTMLString(let x):
				return x.apply(instance, storage) { i, s, v in
					let n = i.loadHTMLString(v.string, baseURL: v.baseURL)
					v.2?.send(value: n)
				}
			case .loadData(let x):
				return x.apply(instance, storage) { i, s, v in
					if #available(OSX 10.11, *) {
						let n = i.load(v.data, mimeType: v.mimeType, characterEncodingName: v.characterEncodingName, baseURL: v.baseURL)
						v.4?.send(value: n)
					}
				}
			case .reload(let x):
				return x.apply(instance, storage) { i, s, v in
					let n = i.reload()
					v?.send(value: n)
				}
			case .reloadFromOrigin(let x):
				return x.apply(instance, storage) { i, s, v in
					let n = i.reloadFromOrigin()
					v?.send(value: n)
				}
			case .goBack(let x):
				return x.apply(instance, storage) { i, s, v in
					let n = i.goBack()
					v?.send(value: n)
				}
			case .goForward(let x):
				return x.apply(instance, storage) { i, s, v in
					let n = i.goForward()
					v?.send(value: n)
				}
			case .goTo(let x):
				return x.apply(instance, storage) { i, s, v in
					let n = i.go(to: v.0)
					v.1?.send(value: n)
				}
			case .stopLoading(let x):
				return x.apply(instance, storage) { i, s, v in i.stopLoading() }
			case .evaluateJavaScript(let x):
				return x.apply(instance, storage) { i, s, v in
					i.evaluateJavaScript(v.javaScriptString) { (output, error) in
						v.1?.send(value: (output, error))
					}
				}
				
			case .didCommit: return nil
			case .didStartProvisionalNavigation: return nil
			case .didReceiveServerRedirectForProvisionalNavigation: return nil
			case .didFail: return nil
			case .didFailProvisionalNavigation: return nil
			case .didFinish: return nil
			case .contentProcessDidTerminate: return nil
			case .decideActionPolicy: return nil
			case .decideResponsePolicy: return nil
			case .didReceiveAuthenticationChallenge: return nil
			case .runJavaScriptAlertPanel: return nil
			case .runJavaScriptConfirmPanel: return nil
			case .runJavaScriptTextInputPanel: return nil
			case .didClose: return nil
			case .runOpenPanel: return nil
			case .createWebView: return nil
			case .shouldPreviewElement: return nil
			case .previewingViewController: return nil
			case .commitPreviewingViewController: return nil
			case .inheritedBinding(let s): return linkedPreparer.applyBinding(s, instance: instance, storage: storage)
			}
		}
	}

	class Storage: View.Storage, WKUIDelegate, WKNavigationDelegate {}

	class Delegate: DynamicDelegate, WKUIDelegate, WKNavigationDelegate {
		required override init() {
			super.init()
		}
		
		var didCommit: SignalInput<WKNavigation>?
		func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
			didCommit!.send(value: navigation)
		}
		
		var didStartProvisionalNavigation: SignalInput<WKNavigation>?
		func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
			didStartProvisionalNavigation!.send(value: navigation)
		}
		
		var didReceiveServerRedirectForProvisionalNavigation: SignalInput<WKNavigation>?
		func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
			didReceiveServerRedirectForProvisionalNavigation!.send(value: navigation)
		}
		
		var didFail: SignalInput<(WKNavigation, Error)>?
		func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
			didFail!.send(value: (navigation, error))
		}
		
		var didFailProvisionalNavigation: SignalInput<(WKNavigation, Error)>?
		func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
			didFailProvisionalNavigation!.send(value: (navigation, error))
		}
		
		var didFinish: SignalInput<WKNavigation>?
		func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
			didFinish!.send(value: navigation)
		}
		
		var contentProcessDidTerminate: SignalInput<()>?
		func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
			contentProcessDidTerminate!.send(value: ())
		}
		
		var decideActionPolicy: SignalInput<(WKNavigationAction, SignalInput<WKNavigationActionPolicy>)>?
		func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
			decideActionPolicy!.send(value: (navigationAction, Input().subscribeWhile(context: .main) { r in decisionHandler(r.value ?? .cancel); return false }))
		}
		
		var decideResponsePolicy: SignalInput<(WKNavigationResponse, SignalInput<WKNavigationResponsePolicy>)>?
		func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
			decideResponsePolicy!.send(value: (navigationResponse, Input().subscribeWhile(context: .main) { r in decisionHandler(r.value ?? .cancel); return false }))
		}
		
		var didReceiveAuthenticationChallenge: SignalInput<(URLAuthenticationChallenge, SignalInput<(URLSession.AuthChallengeDisposition, URLCredential?)>)>?
		func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
			didReceiveAuthenticationChallenge!.send(value: (challenge, Input().subscribeWhile(context: .main) { r in completionHandler(r.value?.0 ?? .cancelAuthenticationChallenge, r.value?.1); return false }))
		}
		
		var runJavaScriptAlertPanel: SignalInput<(message: String, frame: WKFrameInfo, SignalInput<()>)>?
		func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
			runJavaScriptAlertPanel!.send(value: (message: message, frame: frame, Input().subscribeWhile(context: .main) { r in completionHandler(); return false }))
		}
		
		var runJavaScriptConfirmPanel: SignalInput<(message: String, frame: WKFrameInfo, SignalInput<Bool>)>?
		func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
			runJavaScriptConfirmPanel!.send(value: (message: message, frame: frame, Input().subscribeWhile(context: .main) { r in completionHandler(r.value ?? false); return false }))
		}
		
		var runJavaScriptTextInputPanel: SignalInput<(prompt: String, defaultText: String?, frame: WKFrameInfo, SignalInput<String?>)>?
		func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
			runJavaScriptTextInputPanel!.send(value: (prompt: prompt, defaultText: defaultText, frame: frame, Input().subscribeWhile(context: .main) { r in completionHandler(r.value ?? nil); return false }))
		}
		
		var createWebView: ((_ webView: WKWebView, _ configuration: WKWebViewConfiguration, _ navigationAction: WKNavigationAction, _ windowFeatures: WKWindowFeatures) -> WKWebView?)?
		func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
			return createWebView!(webView, configuration, navigationAction, windowFeatures)
		}

		var didClose: SignalInput<()>?
		func webViewDidClose(_ webView: WKWebView) {
			didClose!.send(value: ())
		}

		#if os(iOS)
			var shouldPreviewElement: Any?
			@available(iOS 10.0, *)
			func webView(_ webView: WKWebView, shouldPreviewElement elementInfo: WKPreviewElementInfo) -> Bool {
				return (shouldPreviewElement as! (_ webView: WKWebView, _ elementInfo: WKPreviewElementInfo) -> Bool)(webView, elementInfo)
			}
			
			var commitPreviewingViewController: ((_ webView: WKWebView, _ previewingViewController: UIViewController) -> Void)?
			func webView(_ webView: WKWebView, commitPreviewingViewController previewingViewController: UIViewController) {
				commitPreviewingViewController!(webView, previewingViewController)
			}
			
			var previewingViewController: Any?
			@available(iOS 10.0, *)
			func webView(_ webView: WKWebView, previewingViewControllerForElement elementInfo: WKPreviewElementInfo, defaultActions previewActions: [WKPreviewActionItem]) -> UIViewController? {
				return (previewingViewController as! (_ webView: WKWebView, _ elementInfo: WKPreviewElementInfo, _ previewActions: [WKPreviewActionItem]) -> UIViewController?)(webView, elementInfo, previewActions)
			}
		#else
			var runOpenPanel: Any?
			@available(OSX 10.12, *)
			func webView(_ webView: WKWebView, runOpenPanelWith parameters: WKOpenPanelParameters, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping ([URL]?) -> Void) {
				(runOpenPanel as! SignalInput<(parameters: WKOpenPanelParameters, frame: WKFrameInfo, completion: SignalInput<[URL]?>)>).send(value: (parameters: parameters, frame: frame, completion: Input().subscribeWhile(context: .main) { r in completionHandler(r.value ?? nil); return false }))
			}
		#endif
	}
}

extension BindingName where Binding: WebViewBinding {
	// You can easily convert the `Binding` cases to `BindingName` using the following Xcode-style regex:
	// Replace: case ([^\(]+)\((.+)\)$
	// With:    static var $1: BindingName<$2, Binding> { return BindingName<$2, Binding>({ v in .webViewBinding(WebView.Binding.$1(v)) }) }
	#if os(iOS)
		static var scrollView: BindingName<StaticValue<ScrollView>, Binding> { return BindingName<StaticValue<ScrollView>, Binding>({ v in .webViewBinding(WebView.Binding.scrollView(v)) }) }
	#endif
	@available(macOS 10.11, *)
	static var customUserAgent: BindingName<DynamicValue<String?>, Binding> { return BindingName<DynamicValue<String?>, Binding>({ v in .webViewBinding(WebView.Binding.customUserAgent(v)) }) }
	#if os(macOS)
		static var allowsMagnification: BindingName<DynamicValue<Bool>, Binding> { return BindingName<DynamicValue<Bool>, Binding>({ v in .webViewBinding(WebView.Binding.allowsMagnification(v)) }) }
		static var magnification: BindingName<DynamicValue<(factor: CGFloat, centeredAt: CGPoint)>, Binding> { return BindingName<DynamicValue<(factor: CGFloat, centeredAt: CGPoint)>, Binding>({ v in .webViewBinding(WebView.Binding.magnification(v)) }) }
	#endif
	static var allowsBackForwardNavigationGestures: BindingName<DynamicValue<Bool>, Binding> { return BindingName<DynamicValue<Bool>, Binding>({ v in .webViewBinding(WebView.Binding.allowsBackForwardNavigationGestures(v)) }) }
	@available(macOS 10.11, *)
	static var allowsLinkPreview: BindingName<DynamicValue<Bool>, Binding> { return BindingName<DynamicValue<Bool>, Binding>({ v in .webViewBinding(WebView.Binding.allowsLinkPreview(v)) }) }
	static var load: BindingName<Signal<(request: URLRequest, SignalInput<WKNavigation?>?)>, Binding> { return BindingName<Signal<(request: URLRequest, SignalInput<WKNavigation?>?)>, Binding>({ v in .webViewBinding(WebView.Binding.load(v)) }) }
	@available(macOS 10.11, *)
	static var loadFile: BindingName<Signal<(url: URL, allowingReadAccessTo: URL, SignalInput<WKNavigation?>?)>, Binding> { return BindingName<Signal<(url: URL, allowingReadAccessTo: URL, SignalInput<WKNavigation?>?)>, Binding>({ v in .webViewBinding(WebView.Binding.loadFile(v)) }) }
	static var loadHTMLString: BindingName<Signal<(string: String, baseURL: URL?, SignalInput<WKNavigation?>?)>, Binding> { return BindingName<Signal<(string: String, baseURL: URL?, SignalInput<WKNavigation?>?)>, Binding>({ v in .webViewBinding(WebView.Binding.loadHTMLString(v)) }) }
	@available(macOS 10.11, *)
	static var loadData: BindingName<Signal<(data: Data, mimeType: String, baseURL: URL, characterEncodingName: String, SignalInput<WKNavigation?>?)>, Binding> { return BindingName<Signal<(data: Data, mimeType: String, baseURL: URL, characterEncodingName: String, SignalInput<WKNavigation?>?)>, Binding>({ v in .webViewBinding(WebView.Binding.loadData(v)) }) }
	static var reload: BindingName<Signal<SignalInput<WKNavigation?>?>, Binding> { return BindingName<Signal<SignalInput<WKNavigation?>?>, Binding>({ v in .webViewBinding(WebView.Binding.reload(v)) }) }
	static var reloadFromOrigin: BindingName<Signal<SignalInput<WKNavigation?>?>, Binding> { return BindingName<Signal<SignalInput<WKNavigation?>?>, Binding>({ v in .webViewBinding(WebView.Binding.reloadFromOrigin(v)) }) }
	static var goBack: BindingName<Signal<SignalInput<WKNavigation?>?>, Binding> { return BindingName<Signal<SignalInput<WKNavigation?>?>, Binding>({ v in .webViewBinding(WebView.Binding.goBack(v)) }) }
	static var goForward: BindingName<Signal<SignalInput<WKNavigation?>?>, Binding> { return BindingName<Signal<SignalInput<WKNavigation?>?>, Binding>({ v in .webViewBinding(WebView.Binding.goForward(v)) }) }
	static var goTo: BindingName<Signal<(WKBackForwardListItem, SignalInput<WKNavigation?>?)>, Binding> { return BindingName<Signal<(WKBackForwardListItem, SignalInput<WKNavigation?>?)>, Binding>({ v in .webViewBinding(WebView.Binding.goTo(v)) }) }
	static var stopLoading: BindingName<Signal<()>, Binding> { return BindingName<Signal<()>, Binding>({ v in .webViewBinding(WebView.Binding.stopLoading(v)) }) }
	static var evaluateJavaScript: BindingName<Signal<(javaScriptString: String, SignalInput<(Any?, Error?)>?)>, Binding> { return BindingName<Signal<(javaScriptString: String, SignalInput<(Any?, Error?)>?)>, Binding>({ v in .webViewBinding(WebView.Binding.evaluateJavaScript(v)) }) }
	static var didCommit: BindingName<SignalInput<WKNavigation>, Binding> { return BindingName<SignalInput<WKNavigation>, Binding>({ v in .webViewBinding(WebView.Binding.didCommit(v)) }) }
	static var didStartProvisionalNavigation: BindingName<SignalInput<WKNavigation>, Binding> { return BindingName<SignalInput<WKNavigation>, Binding>({ v in .webViewBinding(WebView.Binding.didStartProvisionalNavigation(v)) }) }
	static var didReceiveServerRedirectForProvisionalNavigation: BindingName<SignalInput<WKNavigation>, Binding> { return BindingName<SignalInput<WKNavigation>, Binding>({ v in .webViewBinding(WebView.Binding.didReceiveServerRedirectForProvisionalNavigation(v)) }) }
	static var didFail: BindingName<SignalInput<(WKNavigation, Error)>, Binding> { return BindingName<SignalInput<(WKNavigation, Error)>, Binding>({ v in .webViewBinding(WebView.Binding.didFail(v)) }) }
	static var didFailProvisionalNavigation: BindingName<SignalInput<(WKNavigation, Error)>, Binding> { return BindingName<SignalInput<(WKNavigation, Error)>, Binding>({ v in .webViewBinding(WebView.Binding.didFailProvisionalNavigation(v)) }) }
	static var didFinish: BindingName<SignalInput<WKNavigation>, Binding> { return BindingName<SignalInput<WKNavigation>, Binding>({ v in .webViewBinding(WebView.Binding.didFinish(v)) }) }
	static var contentProcessDidTerminate: BindingName<SignalInput<()>, Binding> { return BindingName<SignalInput<()>, Binding>({ v in .webViewBinding(WebView.Binding.contentProcessDidTerminate(v)) }) }
	static var decideActionPolicy: BindingName<SignalInput<(WKNavigationAction, SignalInput<WKNavigationActionPolicy>)>, Binding> { return BindingName<SignalInput<(WKNavigationAction, SignalInput<WKNavigationActionPolicy>)>, Binding>({ v in .webViewBinding(WebView.Binding.decideActionPolicy(v)) }) }
	static var decideResponsePolicy: BindingName<SignalInput<(WKNavigationResponse, SignalInput<WKNavigationResponsePolicy>)>, Binding> { return BindingName<SignalInput<(WKNavigationResponse, SignalInput<WKNavigationResponsePolicy>)>, Binding>({ v in .webViewBinding(WebView.Binding.decideResponsePolicy(v)) }) }
	static var didReceiveAuthenticationChallenge: BindingName<SignalInput<(URLAuthenticationChallenge, SignalInput<(URLSession.AuthChallengeDisposition, URLCredential?)>)>, Binding> { return BindingName<SignalInput<(URLAuthenticationChallenge, SignalInput<(URLSession.AuthChallengeDisposition, URLCredential?)>)>, Binding>({ v in .webViewBinding(WebView.Binding.didReceiveAuthenticationChallenge(v)) }) }
	static var runJavaScriptAlertPanel: BindingName<SignalInput<(message: String, frame: WKFrameInfo, SignalInput<()>)>, Binding> { return BindingName<SignalInput<(message: String, frame: WKFrameInfo, SignalInput<()>)>, Binding>({ v in .webViewBinding(WebView.Binding.runJavaScriptAlertPanel(v)) }) }
	static var runJavaScriptConfirmPanel: BindingName<SignalInput<(message: String, frame: WKFrameInfo, SignalInput<Bool>)>, Binding> { return BindingName<SignalInput<(message: String, frame: WKFrameInfo, SignalInput<Bool>)>, Binding>({ v in .webViewBinding(WebView.Binding.runJavaScriptConfirmPanel(v)) }) }
	static var runJavaScriptTextInputPanel: BindingName<SignalInput<(prompt: String, defaultText: String?, frame: WKFrameInfo, SignalInput<String?>)>, Binding> { return BindingName<SignalInput<(prompt: String, defaultText: String?, frame: WKFrameInfo, SignalInput<String?>)>, Binding>({ v in .webViewBinding(WebView.Binding.runJavaScriptTextInputPanel(v)) }) }
	@available(OSX 10.11, iOS 9.0, *)
	static var didClose: BindingName<SignalInput<()>, Binding> { return BindingName<SignalInput<()>, Binding>({ v in .webViewBinding(WebView.Binding.didClose(v)) }) }
	#if os(macOS)
		@available(OSX 10.12, *)
		static var runOpenPanel: BindingName<SignalInput<(parameters: WKOpenPanelParameters, frame: WKFrameInfo, completion: SignalInput<[URL]?>)>, Binding> { return BindingName<SignalInput<(parameters: WKOpenPanelParameters, frame: WKFrameInfo, completion: SignalInput<[URL]?>)>, Binding>({ v in .webViewBinding(WebView.Binding.runOpenPanel(v)) }) }
	#endif
	static var createWebView: BindingName<(_ webView: WKWebView, _ with: WKWebViewConfiguration, _ for: WKNavigationAction, _ windowFeatures: WKWindowFeatures) -> WKWebView?, Binding> { return BindingName<(_ webView: WKWebView, _ with: WKWebViewConfiguration, _ for: WKNavigationAction, _ windowFeatures: WKWindowFeatures) -> WKWebView?, Binding>({ v in .webViewBinding(WebView.Binding.createWebView(v)) }) }
	#if os(iOS)
		@available(iOS 10.0, *)
		static var shouldPreviewElement: BindingName<(_ webView: WKWebView, _ elementInfo: WKPreviewElementInfo) -> Bool, Binding> { return BindingName<(_ webView: WKWebView, _ elementInfo: WKPreviewElementInfo) -> Bool, Binding>({ v in .webViewBinding(WebView.Binding.shouldPreviewElement(v)) }) }
		@available(iOS 10.0, *)
		static var previewingViewController: BindingName<(_ webView: WKWebView, _ elementInfo: WKPreviewElementInfo, _ previewActions: [WKPreviewActionItem]) -> UIViewController?, Binding> { return BindingName<(_ webView: WKWebView, _ elementInfo: WKPreviewElementInfo, _ previewActions: [WKPreviewActionItem]) -> UIViewController?, Binding>({ v in .webViewBinding(WebView.Binding.previewingViewController(v)) }) }
		@available(iOS 10.0, *)
		static var commitPreviewingViewController: BindingName<(_ webView: WKWebView, _ previewingViewController: UIViewController) -> Void, Binding> { return BindingName<(_ webView: WKWebView, _ previewingViewController: UIViewController) -> Void, Binding>({ v in .webViewBinding(WebView.Binding.commitPreviewingViewController(v)) }) }
	#endif
}

protocol WebViewInstance: ViewInstance {
	var webViewInstance: WKWebView { get }
}
extension WebViewInstance {
	var viewInstance: Layout.View { return webViewInstance }
}
extension WKWebView: WebViewInstance {
	var webViewInstance: WKWebView { return self }
}

protocol WebViewBinding: ViewBinding {
	static func webViewBinding(_ binding: WebView.Binding) -> Self
}
extension WebViewBinding {
	static func viewBinding(_ binding: View.Binding) -> Self {
		return Self.webViewBinding(.inheritedBinding(binding))
	}
}

// MARK: ### CwlStackView.swift ###

class StackView: ConstructingBinder, StackViewInstance {
#if os(macOS)
	typealias NSUIView = NSView
	typealias NSUIStackView = NSStackView
	typealias NSUIStackViewDistribution = NSStackView.Gravity
	typealias NSUIStackViewAlignment = NSLayoutConstraint.Attribute
	typealias NSUIUserInterfaceLayoutOrientation = NSUserInterfaceLayoutOrientation
	typealias NSUILayoutPriority = NSLayoutConstraint.Priority
#else
	typealias NSUIView = UIView
	typealias NSUIStackView = UIStackView
	typealias NSUIStackViewDistribution = UIStackViewDistribution
	typealias NSUIStackViewAlignment = UIStackViewAlignment
	typealias NSUIUserInterfaceLayoutOrientation = UILayoutConstraintAxis
	typealias NSUILayoutPriority = UILayoutPriority
#endif

	typealias Instance = NSUIStackView
	typealias Inherited = View
	
	var state: BinderConstructionState<Instance, Binding>
	required init(subclass: Instance.Type = Instance.self, bindings: [Binding]) {
		state = .pending(BinderParameters(subclass: subclass, bindings: bindings))
	}
	static func bindingToInherited(_ binding: Binding) -> Inherited.Binding? {
		if case .inheritedBinding(let s) = binding { return s } else { return nil }
	}
	var stackViewInstance: Instance { return instance() }
	
	enum Binding: StackViewBinding {
		typealias Binder = StackView
		static func stackViewBinding(_ binding: Binding) -> Binding { return binding }
		case inheritedBinding(Inherited.Binding)
		
		// 1. Value bindings may be applied at construction and may subsequently change.
		case alignment(DynamicValue<NSUIStackViewAlignment>)
		case spacing(DynamicValue<CGFloat>)
		case distribution(DynamicValue<NSUIStackViewDistribution>)
		case axis(DynamicValue<NSUIUserInterfaceLayoutOrientation>)
		case views(DynamicValue<[ViewInstance]>)
		#if os(macOS)
			case horizontalClippingResistance(DynamicValue<NSUILayoutPriority>)
			case verticalClippingResistance(DynamicValue<NSUILayoutPriority>)
			case horizontalHuggingPriority(DynamicValue<NSUILayoutPriority>)
			case verticalHuggingPriority(DynamicValue<NSUILayoutPriority>)
			case edgeInsets(DynamicValue<NSEdgeInsets>)
			@available(*, unavailable)
			case isLayoutMarginsRelativeArrangement(())
		#else
			case isLayoutMarginsRelativeArrangement(DynamicValue<Bool>)
			@available(*, unavailable)
			case edgeInsets(())
			@available(*, unavailable)
			case horizontalClippingResistance(DynamicValue<NSUILayoutPriority>)
			@available(*, unavailable)
			case verticalClippingResistance(DynamicValue<NSUILayoutPriority>)
			@available(*, unavailable)
			case horizontalHuggingPriority(DynamicValue<NSUILayoutPriority>)
			@available(*, unavailable)
			case verticalHuggingPriority(DynamicValue<NSUILayoutPriority>)
		#endif
		
		// 2. Signal bindings are performed on the object after construction.
		
		// 3. Action bindings are triggered by the object after construction.
		
	  // 4. Delegate bindings require synchronous evaluation within the object's context.
	}

	struct Preparer: ConstructingPreparer {
		typealias Binder = StackView
		var linkedPreparer = Inherited.Preparer()
		
		func constructStorage() -> Binder.Storage { return Storage() }
		func constructInstance(subclass: Binder.Instance.Type) -> Binder.Instance { return subclass.init() }
		
		init() {}
		
		func applyBinding(_ binding: Binding, instance: Instance, storage: Storage) -> Cancellable? {
			switch binding {
			case .alignment(let x): return x.apply(instance, storage) { i, s, v in i.alignment = v }
			case .spacing(let x): return x.apply(instance, storage) { i, s, v in i.spacing = v }
			case .distribution(let x):
				return x.apply(instance, storage) { i, s, v in
					#if os(macOS)
						s.gravity = v
						if #available(OSX 10.11, *) {
							i.setViews(i.arrangedSubviews, in: s.gravity)
						} else {
							i.setViews(i.subviews, in: s.gravity)
						}
					#else
						i.distribution = v
					#endif
				}
			case .axis(let x):
				return x.apply(instance, storage) { i, s, v in
					#if os(macOS)
						i.orientation = v
					#else
						i.axis = v
					#endif
				}
			case .horizontalClippingResistance(let x):
				#if os(macOS)
					return x.apply(instance, storage) { i, s, v in i.setClippingResistancePriority(v, for: .horizontal) }
				#else
					return nil
				#endif
			case .verticalClippingResistance(let x):
				#if os(macOS)
					return x.apply(instance, storage) { i, s, v in i.setClippingResistancePriority(v, for: .vertical) }
				#else
					return nil
				#endif
			case .horizontalHuggingPriority(let x):
				#if os(macOS)
					return x.apply(instance, storage) { i, s, v in i.setHuggingPriority(v, for: .horizontal) }
				#else
					return nil
				#endif
			case .verticalHuggingPriority(let x):
				#if os(macOS)
					return x.apply(instance, storage) { i, s, v in i.setHuggingPriority(v, for: .vertical) }
				#else
					return nil
				#endif
			case .views(let x):
				return x.apply(instance, storage) { i, s, v in
					#if os(macOS)
						i.setViews(v.map { $0.view() }, in: s.gravity)
					#else
						for view in i.arrangedSubviews {
							view.removeFromSuperview()
						}
						for view in v {
							i.addArrangedSubview(view.viewInstance)
						}
					#endif
				}
			case .edgeInsets(let x):
				#if os(macOS)
					return x.apply(instance, storage) { i, s, v in i.edgeInsets = v }
				#else
					return nil
				#endif
			case .isLayoutMarginsRelativeArrangement(let x):
				#if os(macOS)
					return nil
				#else
					return x.apply(instance, storage) { i, s, v in i.isLayoutMarginsRelativeArrangement = v }
				#endif
			case .inheritedBinding(let s): return linkedPreparer.applyBinding(s, instance: instance, storage: storage)
			}
		}
	}

	#if os(macOS)
		class Storage: View.Storage {
			var gravity: NSStackView.Gravity = .center
		}
	#else
		typealias Storage = View.Storage
	#endif
}

extension BindingName where Binding: StackViewBinding {
	// You can easily convert the `Binding` cases to `BindingName` using the following Xcode-style regex:
	// Replace: case ([^\(]+)\((.+)\)$
	// With:    static var $1: BindingName<$2, Binding> { return BindingName<$2, Binding>({ v in .stackViewBinding(StackView.Binding.$1(v)) }) }
	static var alignment: BindingName<DynamicValue<StackView.NSUIStackViewAlignment>, Binding> { return BindingName<DynamicValue<StackView.NSUIStackViewAlignment>, Binding>({ v in .stackViewBinding(StackView.Binding.alignment(v)) }) }
	static var spacing: BindingName<DynamicValue<CGFloat>, Binding> { return BindingName<DynamicValue<CGFloat>, Binding>({ v in .stackViewBinding(StackView.Binding.spacing(v)) }) }
	static var distribution: BindingName<DynamicValue<StackView.NSUIStackViewDistribution>, Binding> { return BindingName<DynamicValue<StackView.NSUIStackViewDistribution>, Binding>({ v in .stackViewBinding(StackView.Binding.distribution(v)) }) }
	static var axis: BindingName<DynamicValue<StackView.NSUIUserInterfaceLayoutOrientation>, Binding> { return BindingName<DynamicValue<StackView.NSUIUserInterfaceLayoutOrientation>, Binding>({ v in .stackViewBinding(StackView.Binding.axis(v)) }) }
	static var views: BindingName<DynamicValue<[ViewInstance]>, Binding> { return BindingName<DynamicValue<[ViewInstance]>, Binding>({ v in .stackViewBinding(StackView.Binding.views(v)) }) }
	#if os(macOS)
		static var horizontalClippingResistance: BindingName<DynamicValue<StackView.NSUILayoutPriority>, Binding> { return BindingName<DynamicValue<StackView.NSUILayoutPriority>, Binding>({ v in .stackViewBinding(StackView.Binding.horizontalClippingResistance(v)) }) }
		static var verticalClippingResistance: BindingName<DynamicValue<StackView.NSUILayoutPriority>, Binding> { return BindingName<DynamicValue<StackView.NSUILayoutPriority>, Binding>({ v in .stackViewBinding(StackView.Binding.verticalClippingResistance(v)) }) }
		static var horizontalHuggingPriority: BindingName<DynamicValue<StackView.NSUILayoutPriority>, Binding> { return BindingName<DynamicValue<StackView.NSUILayoutPriority>, Binding>({ v in .stackViewBinding(StackView.Binding.horizontalHuggingPriority(v)) }) }
		static var verticalHuggingPriority: BindingName<DynamicValue<StackView.NSUILayoutPriority>, Binding> { return BindingName<DynamicValue<StackView.NSUILayoutPriority>, Binding>({ v in .stackViewBinding(StackView.Binding.verticalHuggingPriority(v)) }) }
		static var edgeInsets: BindingName<DynamicValue<NSEdgeInsets>, Binding> { return BindingName<DynamicValue<NSEdgeInsets>, Binding>({ v in .stackViewBinding(StackView.Binding.edgeInsets(v)) }) }
		@available(*, unavailable)
		static var isLayoutMarginsRelativeArrangement: BindingName<(), Binding> { return BindingName<(), Binding>({ v in .stackViewBinding(StackView.Binding.isLayoutMarginsRelativeArrangement(v)) }) }
	#endif
}

protocol StackViewInstance: ViewInstance {
	var stackViewInstance: StackView.Instance { get }
}
extension StackViewInstance {
	var viewInstance: View.Instance { return stackViewInstance }
}
extension StackView.Instance: StackViewInstance {
	var stackViewInstance: StackView.Instance { return self }
}

protocol StackViewBinding: ViewBinding {
	static func stackViewBinding(_ binding: StackView.Binding) -> Self
}

extension StackViewBinding {
	static func viewBinding(_ binding: View.Binding) -> Self {
		return Self.stackViewBinding(.inheritedBinding(binding))
	}
}

// MARK: ### CwlLayer.swift ###

class Layer: ConstructingBinder, LayerInstance {
	typealias Instance = CALayer
	typealias Inherited = BackingLayer

	var state: BinderConstructionState<Instance, Binding>
	required init(subclass: Instance.Type = Instance.self, bindings: [Binding]) {
		state = .pending(BinderParameters(subclass: subclass, bindings: bindings))
	}
	static func bindingToInherited(_ binding: Binding) -> Inherited.Binding? {
		if case .inheritedBinding(let s) = binding { return s } else { return nil }
	}
	var layerInstance: Instance { return instance() }
	
	enum Binding: LayerBinding {
		typealias Binder = Layer
		static func layerBinding(_ binding: Binding) -> Binding { return binding }
		case inheritedBinding(Inherited.Binding)

		//	1. Value bindings may be applied at construction and may subsequently change.
		#if os(macOS)
			case constraints(DynamicValue<[CAConstraint]>)
		#else
			@available(*, unavailable)
			case constraints(())
		#endif

		//	2. Signal bindings are performed on the object after construction.

		//	3. Action bindings are triggered by the object after construction.

		//	4. Delegate bindings require synchronous evaluation within the object's context.
		case display((CALayer) -> Void)
		case draw((CALayer, CGContext) -> Void)
	}

	struct Preparer: ConstructingPreparer {
		typealias Binder = Layer
		var linkedPreparer = Inherited.Preparer()
		
		func constructStorage() -> Binder.Storage { return Storage() }
		func constructInstance(subclass: Binder.Instance.Type) -> Binder.Instance { return subclass.init() }
		
		init() {
			self.init(delegateClass: InternalDelegate.self)
		}
		init<Value>(delegateClass: Value.Type) where Value: InternalDelegate {
			self.delegateClass = delegateClass
		}
		let delegateClass: InternalDelegate.Type
		var possibleDelegate: InternalDelegate? = nil
		mutating func delegate() -> InternalDelegate {
			if let d = possibleDelegate {
				return d
			} else {
				let d = delegateClass.init()
				possibleDelegate = d
				return d
			}
		}
		
		mutating func prepareBinding(_ binding: Binding) {
			switch binding {
			case .display(let x):
				let s = #selector(CALayerDelegate.display(_:))
				delegate().addSelector(s).display = x
			case .draw(let x):
				let s = #selector(CALayerDelegate.draw(_:in:))
				delegate().addSelector(s).drawLayer = x
			case .inheritedBinding(let x): linkedPreparer.prepareBinding(x)
			default: break
			}
		}
		
		mutating func prepareInstance(_ instance: Instance, storage: Storage) {
			// Don't steal the delegate from the view if already set
			if possibleDelegate != nil {
				precondition(instance.delegate == nil, "Conflicting delegate applied to instance")
				storage.dynamicDelegate = possibleDelegate
				instance.delegate = storage
			}
			
			linkedPreparer.prepareInstance(instance, storage: storage)
		}
		
		func applyBinding(_ binding: Binding, instance: Instance, storage: Storage) -> Cancellable? {
			switch binding {
			case .constraints(let x):
				#if os(macOS)
					return x.apply(instance, storage) { i, s, v in i.constraints = v }
				#else
					return nil
				#endif
			case .display: return nil
			case .draw: return nil
			case .inheritedBinding(let s): return linkedPreparer.applyBinding(s, instance: instance, storage: storage)
			}
		}
	}

	class Storage: BackingLayer.Storage, CALayerDelegate {}

	class InternalDelegate: DynamicDelegate, CALayerDelegate {
		required override init() {
			super.init()
		}
		
		var display: ((CALayer) -> Void)?
		func display(_ layer: CALayer) {
			return display!(layer)
		}
		
		var drawLayer: ((CALayer, CGContext) -> Void)?
		@objc(drawLayer:inContext:) func draw(_ layer: CALayer, in ctx: CGContext) {
			return drawLayer!(layer, ctx)
		}
		
		var layoutSublayers: ((CALayer) -> Void)?
		func layoutSublayers(of layer: CALayer) {
			return layoutSublayers!(layer)
		}
		
		var action: ((CALayer, String) -> CAAction?)?
		func action(for layer: CALayer, forKey event: String) -> CAAction? {
			return action!(layer, event)
		}
	}
}

extension BindingName where Binding: LayerBinding {
	// You can easily convert the `Binding` cases to `BindingName` using the following Xcode-style regex:
	// Replace: case ([^\(]+)\((.+)\)$
	// With:    static var $1: BindingName<$2, Binding> { return BindingName<$2, Binding>({ v in .layerBinding(Layer.Binding.$1(v)) }) }
	#if os(macOS)
		static var constraints: BindingName<DynamicValue<[CAConstraint]>, Binding> { return BindingName<DynamicValue<[CAConstraint]>, Binding>({ v in .layerBinding(Layer.Binding.constraints(v)) }) }
	#endif
	static var display: BindingName<(CALayer) -> Void, Binding> { return BindingName<(CALayer) -> Void, Binding>({ v in .layerBinding(Layer.Binding.display(v)) }) }
	static var draw: BindingName<(CALayer, CGContext) -> Void, Binding> { return BindingName<(CALayer, CGContext) -> Void, Binding>({ v in .layerBinding(Layer.Binding.draw(v)) }) }
}

protocol LayerInstance {
	var layerInstance: Layer.Instance { get }
}
extension Layer.Instance: LayerInstance {
	var layerInstance: Layer.Instance { return self }
}

protocol LayerBinding: BackingLayerBinding {
	static func layerBinding(_ binding: Layer.Binding) -> Self
}

extension LayerBinding {
	static func backingLayerBinding(_ binding: BackingLayer.Binding) -> Self {
		return Self.layerBinding(.inheritedBinding(binding))
	}
}
